package com.ant.storage.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.ant.storage.common.ResultCode;
import com.ant.storage.common.ResultVo;
import com.ant.storage.dto.DingDto;
import com.ant.storage.dto.ReimburseInfoDto;
import com.ant.storage.dto.ReimburseInfosDto;
import com.ant.storage.handler.AntException;
import com.ant.storage.mapper.CapitalAccountMapper;
import com.ant.storage.mapper.ReimburseInfoMapper;
import com.ant.storage.pojo.*;
import com.ant.storage.service.*;
import com.ant.storage.utils.DingDingUtil;
import com.ant.storage.utils.RandomUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.taobao.api.ApiException;
import lombok.SneakyThrows;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.ServletContext;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author hzd
 * @since 2023-09-22
 */
@Service
public class ReimburseInfoServiceImpl extends ServiceImpl<ReimburseInfoMapper, ReimburseInfo> implements IReimburseInfoService {


    @Autowired
    public ServletContext servletContext;


    @Resource
    private CapitalAccountMapper capitalAccountMapper;


    @Resource
    private IPurchaserRecordImgService imgService;

    @Resource
    private IAuditListService auditListService;

    @Resource
    private IReimburseDetailService detailService;

    @Resource
    private IReimburseInfoLogService infoLogService;


    @Override
    public PageInfo<ReimburseInfo> getReimburseInfoPageList(ReimburseInfoDto dto) {
        try {
            PageHelper.startPage(dto.getPageIndex(), dto.getPageSize());
            QueryWrapper<ReimburseInfo> wrapper = new QueryWrapper<>();
            if (StringUtils.isNotEmpty(dto.getReimbursementNumber())) {
                wrapper.lambda().eq(ReimburseInfo::getReimbursementNumber, dto.getReimbursementNumber());
            }
            if (StringUtils.isNotEmpty(dto.getReimbursementType())) {
                wrapper.lambda().eq(ReimburseInfo::getReimbursementType, dto.getReimbursementType());
            }
            UserInfo userInfo = (UserInfo) servletContext.getAttribute("userInfo");
            if (!userInfo.getRoles().equals("vadmin")) {
                wrapper.lambda().in(ReimburseInfo::getCityId, userInfo.getCityId());
            }
            wrapper.orderByDesc("id");
            List<ReimburseInfo> reimbursementList = this.baseMapper.selectList(wrapper);
            List<ReimburseInfo> list = reimbursementList.stream().map(item -> {
                CapitalAccount account =
                        capitalAccountMapper.selectOne(new QueryWrapper<CapitalAccount>().lambda().eq(CapitalAccount::getId,
                                item.getReimbursementType()));
                if (account != null) {
                    item.setReimbursementTypeText(account.getAccountName());
                }
                //获取钉钉审核
                List<AuditList> auditList = auditListService.list(new QueryWrapper<AuditList>().eq("parent_id",
                        item.getId())
                        .eq("process_type", "reimbursementInfo"));
                item.setAuditList(auditList);
                if (item.getInvoice() != null) {
                    ArrayList<String> ids = new ArrayList<String>(Arrays.asList(item.getInvoice().split(",")));
                    List<PurchaserRecordImg> recordImg = imgService.list(new QueryWrapper<PurchaserRecordImg>().in(
                            "id", ids));
                    item.setInvoiceText(recordImg);
                }
                return item;
            }).collect(Collectors.toList());
            PageInfo<ReimburseInfo> pageInfo = new PageInfo<>(reimbursementList);
            pageInfo.setList(list);
            return pageInfo;
        } catch (Exception e) {
            throw new AntException(ResultCode.BODY_NOT_MATCH);
        }
    }

    @Override
    public ResultVo reimburseInfoSave(ReimburseInfosDto dto) {
        try {
            UserInfo userInfo = (UserInfo) servletContext.getAttribute("userInfo");
            dto.setReimbursementNumber("RCD" + RandomUtil.getOrderNumbers(this.baseMapper.selectLastID()));
            dto.setUserId(userInfo.getNameId());
            dto.setCityId(userInfo.getCityId());
            dto.setDepId(userInfo.getDepId());
            dto.setCreatorBy(userInfo.getNameId());
            dto.setCreationTime(new Date());
            this.baseMapper.insert(dto);
            if (dto.getDetailList().size() == 0) {
                throw new AntException(ResultCode.NOT_FOUND);
            }
            dto.getDetailList().stream().forEach(item -> {
                item.setParentId(dto.getId());
                detailService.save(item);
            });
            dto.setIsApproved(0);

            if (dto.getIsApproved() == 1) {
                // 判断是否为空
                AuditList auditList = new AuditList();
                auditList.setParentId(dto.getId());
                auditList.setProcessType("reimburseInfo");
                auditList.setCreationTime(new Date());
                auditList.setName(userInfo.getNameId().toString());
                if (dto.getApproval().size() == 0 || dto.getApproval() == null) {
                    throw new AntException("请选择审批人员");
                }
                // 添加审核记录
                for (String str : dto.getApproval()) {
                    auditList.setNameId(str);
                    auditList.setTypes("1");
                    auditListService.save(auditList);
                }
                if (dto.getNotify().size() == 0 || dto.getNotify() == null) {
                    throw new AntException("请选择抄送人");
                }
                for (String str2 : dto.getNotify()) {
                    auditList.setNameId(str2);
                    auditList.setTypes("2");
                    auditListService.save(auditList);
                }
                // 发起钉钉审批
                // 通过 getUserId()
                DingDto ding = new DingDto();
                ding.setOriginator_userid(userInfo.getDingTalk());
                try {
                    Long personneDeplList = DingDingUtil.getPersonneDepld(userInfo.getDingTalk(),
                            DingDingUtil.obtainToken());
                    Integer depId = personneDeplList.intValue();
                    ding.setDeptId(depId);
                } catch (ApiException e) {
                    e.printStackTrace();
                }
                //  dto.setDeptId(149215742);
                ding.setId(dto.getId());
                ding.setApprover_userid(dto.getApproval());
                ding.setCc_userId(dto.getNotify());
                ding.setCity(userInfo.getCityName());
                ding.setDepartment(userInfo.getDepName());
                ding.setRemarks(dto.getRemarks());
                //采购申请钉钉审批
                try {
                    String process_instance_ids = addDingDing(ding);
                    return ResultVo.success("保存成功");
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            return ResultVo.success("保存成功");
        } catch (Exception e) {
            throw new AntException(ResultCode.FAILURE.getResultCode(), e.getMessage());
        }
    }

    /**
     * 提交钉钉审批
     *
     * @param dto
     * @return
     */
    @SneakyThrows
    @Transactional
    public String addDingDing(DingDto dto) throws ApiException {
        dto.setAccess_token(DingDingUtil.obtainToken());
        String process_instance_id = DingDingUtil.OldGoodeAppalyAndApprove(dto);
        return process_instance_id;
    }

    @Override
    @Transactional()
    public ResultVo applyAdopt(ReimburseInfoLog log) {
        UserInfo userInfo = (UserInfo) servletContext.getAttribute("userInfo");
        ReimburseInfo selectOne = this.baseMapper.selectOne(new QueryWrapper<ReimburseInfo>().eq("id",
                log.getReimburseInfoId()));
        if (selectOne == null) {
            throw new AntException(ResultCode.NOT_FOUND);
        } else {
            ReimburseInfo info = new ReimburseInfo();
            info.setId(log.getReimburseInfoId());
            info.setOpinion(log.getOpinion());
            info.setAmount(log.getAmount());
            info.setProcessState(log.getStates());
            info.setHandleBy(userInfo.getNameId());
            info.setHandleTime(new Date());
            this.baseMapper.updateById(info);
            log.setHandlerId(userInfo.getNameId());
            log.setHandlerTime(new Date());
            infoLogService.save(log);
            return ResultVo.success("操作成功");
        }
    }

    @Override
    public ReimburseInfo ReimburseInfoById(Integer id) {
        ReimburseInfo info = this.baseMapper.selectOne(new QueryWrapper<ReimburseInfo>().eq("id", id));
        if (info == null) {
            throw new AntException(ResultCode.NOT_FOUND);
        }
        ReimburseInfosDto dto = new ReimburseInfosDto();
        BeanUtil.copyProperties(info, dto);
        dto.setReimbursementTypeText(getCapitalAccount(info.getReimbursementType()));

        dto.setInvoiceTypeText(getCapitalAccount(info.getInvoiceType()));

        List<ReimburseDetail> details = detailService.list(new QueryWrapper<ReimburseDetail>().eq("parent_id",
                info.getId()));
        if (details == null) {
            throw new AntException(ResultCode.NOT_FOUND);
        }
        details.stream().forEach(it -> {
            List<PurchaserRecordImg> imgs = imgService.list(new QueryWrapper<PurchaserRecordImg>().in("id",
                    Arrays.asList(it.getProjectAnnex().split(","))));
            it.setImgList(imgs);
            it.setProjectName(getCapitalAccount(it.getTypeId()));
        });
        dto.setDetailList(details);
        return dto;
    }

    public String getCapitalAccount(Integer id){
        CapitalAccount account = capitalAccountMapper.selectOne(new QueryWrapper<CapitalAccount>().lambda()
                .eq(CapitalAccount::getId, id));
        if(account==null){
            return null;
        }
        return account.getAccountName();
    }
}
